package com.kmxd.ams.app.arrange.command;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kmxd.ams.client.archive.IArchiveFieldSvc;
import com.kmxd.ams.client.archive.IArchiveRelationSvc;
import com.kmxd.ams.client.archive.vo.ArchiveFieldVO;
import com.kmxd.ams.client.arrange.IDocumentSvc;
import com.kmxd.ams.client.arrange.dto.AssociatedWithDataDTO;
import com.kmxd.ams.client.arrange.dto.AssociatedWithMetaDTO;
import com.kmxd.ams.core.common.constant.ErrorCode;
import com.kmxd.ams.core.common.enums.AssociatedEnum;
import com.kmxd.ams.core.common.enums.AssociatedSourceEnum;
import com.kmxd.ams.core.exception.BizTipException;
import com.kmxd.ams.core.util.ConvertUtil;
import com.kmxd.ams.infra.archive.entity.ArchiveRelation;
import com.kmxd.ams.infra.arrange.base.BaseBO;
import com.kmxd.ams.infra.arrange.entity.Document;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 关联档案
 *
 * @author nickbi
 */
@Slf4j
@Component
@AllArgsConstructor
public class AssociatedFilesCmd {
  private final IDocumentSvc documentSvc;
  private final IArchiveRelationSvc archiveRelationSvc;
  private final IArchiveFieldSvc archiveFieldSvc;

  /**
   * 按数据设置关联关系
   *
   * @param req
   */
  public void associatedWithData(AssociatedWithDataDTO req) {
    Document qry = ConvertUtil.toBean(req, Document.class);
    Document document =
        Optional.ofNullable(documentSvc.view(qry))
            .orElseThrow(() -> BizTipException.instance(ErrorCode.NOT_FOUND, "未找到文档信息"));
    BaseBO qryRefer = new BaseBO();
    qryRefer.setTableId(req.getReferTableId());
    qryRefer.setArchTypeId(req.getReferArchTypeId());
    qryRefer.setDocIds(req.getDocIds());
    List<Document> documentList =
        Optional.ofNullable(documentSvc.selectListByIds(qryRefer))
            .orElseThrow(() -> BizTipException.instance(ErrorCode.NOT_FOUND, "未找到文档信息"));
    if (ObjectUtil.isEmpty(documentList)) {
      return;
    }
    List<ArchiveRelation> relationList =
        documentList.stream()
            .map(
                doc -> {
                  ArchiveRelation relation = ConvertUtil.toBean(doc, ArchiveRelation.class);
                  // 复制门类，表名信息
                  BeanUtil.copyProperties(req, relation);
                  relation.setReferDataId(doc.getId());
                  relation.setRelationType(AssociatedEnum.DATA.getCode());
                  relation.setDataId(document.getId());
                  relation.setSourceIdentity(AssociatedSourceEnum.MANUAL.getCode());
                  relation.setSourceInfo(AssociatedSourceEnum.MANUAL.getDesc());
                  relation.setId(null);
                  // 检测数据重复
                  ArchiveRelation one =
                      archiveRelationSvc.getOne(
                          Wrappers.<ArchiveRelation>lambdaQuery()
                              .eq(ArchiveRelation::getTableId, relation.getTableId())
                              .eq(ArchiveRelation::getDataId, relation.getDataId())
                              .eq(ArchiveRelation::getRelationType, AssociatedEnum.DATA.getCode())
                              .eq(ArchiveRelation::getReferTableId, relation.getReferTableId())
                              .eq(ArchiveRelation::getReferDataId, relation.getReferDataId())
                              .last(" " + "limit 1"));
                  if (Objects.nonNull(one)) {
                    throw BizTipException.instance(ErrorCode.ARCHIVE_DATA_EXIST, "数据已关联");
                  }
                  return relation;
                })
            .collect(Collectors.toList());
    archiveRelationSvc.saveBatch(relationList);
  }

  /**
   * 按元数据设置关联关系
   *
   * @param req
   */
  public void associatedWithMeta(AssociatedWithMetaDTO req) {
    Document qry = ConvertUtil.toBean(req, Document.class);
    Document document =
        Optional.ofNullable(documentSvc.view(qry))
            .orElseThrow(() -> BizTipException.instance(ErrorCode.NOT_FOUND, "未找到文档信息"));
    ArchiveFieldVO fieldVO =
        Optional.ofNullable(archiveFieldSvc.view(req.getRelationFieldId()))
            .orElseThrow(() -> BizTipException.instance(ErrorCode.NOT_FOUND, "未找到关联字段信息"));
    ArchiveRelation relation = new ArchiveRelation();
    relation.setRelationFieldId(fieldVO.getId());
    relation.setReferArchTypeId(fieldVO.getArchTypeId());
    relation.setReferTableId(fieldVO.getTableId());
    relation.setRelationType(AssociatedEnum.META_DATA.getCode());
    relation.setDataId(document.getId());
    relation.setSourceIdentity(AssociatedSourceEnum.MANUAL.getCode());
    relation.setSourceInfo(AssociatedSourceEnum.MANUAL.getDesc());
    relation.setId(null);
    // 检测数据重复
    ArchiveRelation one =
        archiveRelationSvc.getOne(
            Wrappers.<ArchiveRelation>lambdaQuery()
                .eq(ArchiveRelation::getTableId, relation.getTableId())
                .eq(ArchiveRelation::getDataId, relation.getDataId())
                .eq(ArchiveRelation::getRelationType, AssociatedEnum.META_DATA.getCode())
                .eq(ArchiveRelation::getReferTableId, relation.getReferTableId())
                .eq(ArchiveRelation::getRelationFieldId, relation.getRelationFieldId())
                .eq(ArchiveRelation::getRelationIdentity, relation.getRelationIdentity())
                .last(" " + "limit 1"));
    if (Objects.nonNull(one)) {
      throw BizTipException.instance(ErrorCode.ARCHIVE_DATA_EXIST, "数据已关联");
    }
    archiveRelationSvc.save(relation);
  }
}
